package it.polimi.swKnights.SWIMv2.ejb.feedbacks;

import it.polimi.swKnights.SWIMv2.ejb.authentication.LoginHandlerLocal;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.Feedback;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.FeedbackPk;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.RegisteredUser;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.InvalidLoginPrivilegesException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.LoginFailException;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Session Bean implementation class FeedbackHandler
 */
@Stateless
public class FeedbackHandler implements FeedbackHandlerRemote
{

	@PersistenceContext(unitName = "swimv2-manager")
	private EntityManager managerUC; // manager handlin the persistence data

	@EJB
	private LoginHandlerLocal loginController;

	@Override
	public List<Map<String, Object>> getFeedbacksOf(String feedbackOwnerUser,
			String askerUserName, String askerPassword)
			throws LoginFailException, InvalidLoginPrivilegesException
	{

		List<Map<String, Object>> lstMapFeedbacks = new ArrayList<Map<String, Object>>();

		this.loginController.checkLoginDataAndPrivileges(askerUserName,
				askerPassword, RegisteredUser.class);

		RegisteredUser feedbackOwner = this.managerUC.getReference(RegisteredUser.class,
				feedbackOwnerUser);

		/*String queryText = ""
				+ "SELECT f.gotBy, hr.title, f.text, f.leftBy, f.rank, f.id "
				+ "FROM HelpRequest AS hr, Feedback as f "
				+ "WHERE f.leftBy=hr.askingUser AND f.gotBy=:asker ";
				+ "AND hr.endDate <= current_date " // scadute: scadenz prima di oggi
				+"AND hr.endDate > :dateplus";   //ma non da + di 30 giorni*/
		
		
		String queryText = ""
				+ "FROM Feedback AS f "
				+ "WHERE f.gotBy=:feedbackOwner " 
				//+ "AND f.disputed=false"
				; 

	
		Query q = null;
		List<?> queryListFeed = null;
		

		q = this.managerUC.createQuery(queryText);
		q.setParameter("feedbackOwner", feedbackOwner.getUserName());
		
		Date now = new Date();
		Date monthAfterNow = new Date(now.getTime() - TimeUnit.DAYS.toMillis(30));
		if(queryText.contains("dateplus"))
			q.setParameter("dateplus", monthAfterNow);
		
		queryListFeed = q.getResultList();

		for (Object f : queryListFeed)
		{
			Feedback feedback = (Feedback) f;
			Map<String, Object> feedbackData = new HashMap<String, Object>();
			
			feedbackData.put("got_by", feedback.getGotByUsername());
			
			if(feedback.getLeftBy() != null)
			{
				feedbackData.put("left_by", feedback.getLeftBy().getUserName());
			}
			else
			{
				feedbackData.put("left_by", "cancelled user");
			}
			
			feedbackData.put("title_feedback", feedback.getText());
			feedbackData.put("rank", feedback.getRank());
			feedbackData.put("id", feedback.getId());
			feedbackData.put("disputed", feedback.getDisputedAsStringLowCase());
			feedbackData.put("positive", feedback.getRank() >=5 ? "good" : "bad");
			lstMapFeedbacks.add(feedbackData);
			
		}

		return lstMapFeedbacks;

	}

	@Override
	public void disputeFeedback(String idFeed, String gotBy, String username,
			String password) throws LoginFailException,
			InvalidLoginPrivilegesException
	{

		this.loginController.checkLoginDataAndPrivileges(username, password,
				RegisteredUser.class);
		this.loginController.checkBanned(username);

		FeedbackPk fPk = new FeedbackPk();
		fPk.setGotBy(gotBy);
		fPk.setId(Integer.parseInt(idFeed));

		Feedback f = this.managerUC.find(Feedback.class, fPk);
		f.setDisputed(true);

		this.managerUC.persist(f);
	}

	@Override
	public Double getUserFeedbackAverage(String userName)
	{
		String averageQuery = "SELECT AVG(f.rank) FROM Feedback as f "
				+ "WHERE f.gotBy=:userName";
		Query query = this.managerUC.createQuery(averageQuery);
		query.setParameter("userName", userName);

		return (Double) query.getSingleResult();
	}

}
